package database

import (
	"go_redis_service/interface/IDatabase"
	"go_redis_service/interface/IResp"
	"go_redis_service/resp/reply"
)

func init() {
	RegisterCommand("Get", execGet, 2)
	RegisterCommand("Set", execSet, -3)
	RegisterCommand("SetNx", execSetNx, 3)
	RegisterCommand("GetSet", execGetSet, 3)
	RegisterCommand("StrLen", execStrLen, 2)
}

func execGet(db *DB, args [][]byte) IResp.Reply {
	key := string(args[0])
	entity, exists := db.GetEntity(key)
	if !exists {
		return reply.NewNullBulkReply()
	}
	return reply.NewBulkReply(entity.Data.([]byte))
}

func execSet(db *DB, args [][]byte) IResp.Reply {
	if len(args) != 2 {
		return reply.NewStadardErrReply("Err args for command set")
	}
	key := string(args[0])
	val := args[1]
	result := db.PutEntity(key, &IDatabase.DataEntity{Data: val})
	return reply.NewIntReply(int64(result))
}

func execSetNx(db *DB, args [][]byte) IResp.Reply {
	if len(args) != 2 {
		return reply.NewStadardErrReply("Err args for command set")
	}
	key := string(args[0])
	val := args[1]
	result := db.PutIfAbsent(key, &IDatabase.DataEntity{Data: val})
	return reply.NewIntReply(int64(result))

}

// execGetSet
// @Description: set 新值 返回旧值
// @param db
// @param args
// @return IResp.Reply
func execGetSet(db *DB, args [][]byte) IResp.Reply {
	if len(args) != 2 {
		return reply.NewStadardErrReply("Err args for command getset")
	}
	key := string(args[0])
	val := args[1]
	entity, exists := db.GetEntity(key)
	if !exists {
		return reply.NewNullBulkReply()
	}
	oldValue := entity.Data.([]byte)
	_ = db.PutEntity(key, &IDatabase.DataEntity{Data: val})
	return reply.NewBulkReply(oldValue)
}

func execStrLen(db *DB, args [][]byte) IResp.Reply {
	key := string(args[0])
	entity, exists := db.GetEntity(key)
	if !exists {
		return reply.NewNullBulkReply()
	}
	val := entity.Data.([]byte)
	return reply.NewIntReply(int64(len(val)))
}
